package com.cheng.xbsc.service.impl;

import com.cheng.xbsc.entity.User;
import com.cheng.xbsc.entity.vo.Result;
import com.cheng.xbsc.mapper.UserMapper;
import com.cheng.xbsc.service.UserService;
import com.cheng.xbsc.util.LoginUserUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Value("${spring.mail.username}")
    private String form;

    @Value("${filePath}")
    private String filePath;

    @Value("${uploadPath}")
    private String uploadPath;

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private HttpSession session;

    @Override
    public Result findByUsername(String username) {
        User user = userMapper.findByUsername(username);
        if (user != null) {
            return new Result(false, "用户名已被注册");
        }
        return new Result(true, "用户名没有被注册");
    }

    @Override
    public Result findByEmail(String email) {
        User user = userMapper.findByEmail(email);
        if (user != null) {
            return new Result(false, "邮箱已被绑定");
        }
        return new Result(true, "邮箱没有被绑定");
    }

    @Override
    public void save(User user) {
        user.setRegisterTime(new Date()); //设置注册时间
        user.setUserPic("https://www.baidu.com/favicon.ico");  //设置默认头像
        userMapper.insert(user);
    }

    @Override
    public Result sendCode(String email) {
        String code = (String) redisTemplate.opsForValue().get("updatePassword:code" + email);
        if (StringUtils.isNotEmpty(code)) {
            return new Result(false, "60秒后才可以再次发送");
        }
        code = RandomStringUtils.randomNumeric(6);
        redisTemplate.opsForValue().set("updatePassword:code" + email, code, 1, TimeUnit.MINUTES);
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(form);
        message.setTo(email);
        message.setSubject("您的验证码是：");
        message.setText(code);
        mailSender.send(message);
        return new Result(true, "发送成功");
    }

    @Override
    public Result forget(String code, User user) {
        String redisCode = (String) redisTemplate.opsForValue().get("updatePassword:code" + user.getEmail());
        if (StringUtils.isNotEmpty(redisCode) && redisCode.equals(code)) {
            userMapper.updatePassword(user);
            //清空缓存
            redisTemplate.delete("updatePassword:code" + user.getEmail());
            return new Result(true, "更新成功");
        }
        return new Result(false, "验证码错误");
    }

    @Override
    public Result login(String code, User user) {
        String sessionCode = (String) session.getAttribute("checkCode");
        if (StringUtils.isNotEmpty(sessionCode) && sessionCode.equals(code)) {
            user = userMapper.findByUsernameAndPassword(user);
            if (user != null) {
                //更新登录时间
                user.setLoginTime(new Date());
                userMapper.updateByPrimaryKey(user);

                if (StringUtils.isNotEmpty(user.getPassword())) {
                    user.setPassword(null);
                }
                //把user存入redis中
                redisTemplate.opsForValue().set("loginUser:" + user.getId(), user, 30, TimeUnit.MINUTES);

                //把userId放入到session中
                session.setAttribute("userId", user.getId());
                return new Result(true, "登录成功", user);
            } else {
                return new Result(false, "用户名或密码错误");
            }
        } else {
            return new Result(false, "验证码错误");
        }
    }

    @Override
    public User findById(Integer userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (StringUtils.isNotEmpty(user.getPassword())) {
            user.setPassword(null);
        }
        return user;
    }

    /**
     * 头像上传
     *
     * @param file
     * @throws IOException
     */
    @Override
    public Result uploadPic(MultipartFile file) throws IOException {

        String dateName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        File dir = new File(filePath + dateName);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        //获取文件名称
        String filename = file.getOriginalFilename();
        //截取文件后缀(.jpg)
        assert filename != null;
        String fileType = filename.substring(filename.lastIndexOf("."));

        String uuid = UUID.randomUUID().toString();

        //重新组装文件名，防止文件名重复覆盖
        filename = uuid + fileType;

        //把图片写入磁盘
        file.transferTo(new File(dir, filename));

        //文件的网络地址
        String userPic = uploadPath + dateName + "/" + filename;

        //更新头像地址
        userMapper.updateUserPicById(LoginUserUtil.getUserId(), userPic);

        User loginUser = LoginUserUtil.getLoginUser();
        assert loginUser != null;
        loginUser.setUserPic(userPic);

        redisTemplate.opsForValue().set("loginUser:" + loginUser.getId(), loginUser, 30, TimeUnit.MINUTES);
        return new Result(true, "头像上传成功", loginUser);
    }

    /**
     * 更新用户信息
     *
     * @param user
     * @return
     */
    @Override
    public User updateUser(User user) {
        user.setId(LoginUserUtil.getUserId());
        userMapper.updateByPrimaryKeySelective(user);

        user = userMapper.selectByPrimaryKey(LoginUserUtil.getUserId());
        if (StringUtils.isNotEmpty(user.getPassword())) {
            user.setPassword(null);
        }
        //更新redis中用户的信息
        redisTemplate.opsForValue().set("loginUser:" + user.getId(), user, 30, TimeUnit.MINUTES);
        return user;
    }

    @Override
    public Result updatePassword(String oldPassword, String newPassword) {
        User user = userMapper.selectByPrimaryKey(LoginUserUtil.getUserId());
        //判断旧密码是否和登录密码相同
        if (user.getPassword().equals(oldPassword)) {
            user.setPassword(newPassword);
            userMapper.updateByPrimaryKeySelective(user);
            //删除缓存和session中的用户的信息
            redisTemplate.delete("loginUser:" + user.getId());
            session.invalidate();
            return new Result(true, "密码修改成功");
        }
        return new Result(false, "旧密码错误");
    }

    @Override
    public void loginOut() {
        //删除redis中的信息
        redisTemplate.delete("loginUser:" + session.getAttribute("userId"));

        //清空session
        session.invalidate();
    }

    @Override
    public User findByWxOpenid(String openid) {
        return userMapper.findByWxOpenid(openid);
    }
}
